package com.zhizhi.model.synthesizes.account.controller;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhizhi.common.base.BaseController;
import com.zhizhi.common.constant.ResponseCodeConst;
import com.zhizhi.common.constant.SysConstant;
import com.zhizhi.common.constant.SystemConstant;
import com.zhizhi.domain.LoginVO;
import com.zhizhi.domain.ResponseDTO;
import com.zhizhi.module.synthesizes.account.entity.Account;
import com.zhizhi.module.synthesizes.account.service.AccountService;
import com.zhizhi.module.synthesizes.sys.service.MessageService;
import com.zhizhi.util.AssertUtil;
import com.zhizhi.util.EasyBeanUtil;
import com.zhizhi.util.ExecutionContext;
import com.zhizhi.util.KeyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author jiake
 * @date 2021/3/2417:20
 */
@RestController
@CrossOrigin
public class AccountController extends BaseController {

    @Autowired
    private AccountService accountService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    private MessageService messageService;

    @Value("${templatecode.register}")
    private String register;



    /**
     * @param phone, ckeckPhone
     * @return com.ahies.stm.app.util.ResponseResult<java.lang.String>
     * @Description: 获取验证码
     * @menu /公共互动平台
     * @status done
     */
    @RequestMapping("/account/login/authenticode")
    @RequiresPermissions({"account_management"})
    public ResponseDTO<String> authenticode(@RequestParam(name = "phone") String phone) {
        if (StringUtils.isBlank(phone)) {
            return ResponseDTO.wrap(ResponseCodeConst.ERROR_ACCOUNT_MOBILE_PHONE_NULL);
        }
        RBucket<String> rBucket = redissonClient.getBucket(SysConstant.AUTHENTICODE_KEY_PRE  + phone);
        String authenticode = "";

        authenticode = String.valueOf((int) (Math.random() * 900000 + 100000));
        String content = "您本次服务的验证码为" + authenticode + "，请在10分钟内使用。请勿向他人透露您的验证码。";
        log.debug(content);
        Map<String, String> param = new HashMap<>();
        param.put("code", authenticode);

        rBucket.set(authenticode, 10, TimeUnit.MINUTES);

        String tempCode = register;
        //Future<Boolean> future = messageService.sendMessage(phone, authenticode, tempCode);
        return ResponseDTO.successWithData(authenticode);
    }


    /**
     *
     * @param phone
     * @param code
     * @return
     */
    @RequestMapping("/account/code/check")
    public ResponseDTO<LoginVO> checkCode(@RequestParam(name = "phone") String phone,
                                         @RequestParam(name = "code") String code) {
        if (StringUtils.isBlank(phone)) {
            return ResponseDTO.wrap(ResponseCodeConst.ERROR_ACCOUNT_MOBILE_PHONE_NULL);
        }
        if(StringUtils.isBlank(code)){
            return ResponseDTO.wrap(ResponseCodeConst.ERROR_CODE_NULL);
        }
        //判断验证码的正确性
        RBucket<String> rBucket = redissonClient.getBucket(SysConstant.AUTHENTICODE_KEY_PRE  + phone);
        rBucket.get();
        String authenticode = "";

        if (null == rBucket) {
            return ResponseDTO.wrap(null,"验证码过期");
        }
         code = rBucket.get();
        if (StringUtils.isBlank(code)) {
            return ResponseDTO.wrap(null,"验证码过期");
        }
        if (!Objects.equals(code, authenticode)) {
            return ResponseDTO.wrap(null,"验证码错误");
        }
        Account account = new Account();
        account.setMobilePhone(phone);
        boolean flag =  accountService.saveOrUpdate(account);
        LoginVO loginVO = new LoginVO();
        if(flag){
            //生成token
            String sessionKey = SystemConstant.KEY_ACCOUNT + account.getId().toString();
            // 生成 token
            String token = KeyUtils.getKey();
            String tokenKey = SystemConstant.KEY_TOKEN + token;
            redisTemplate.opsForValue().set(sessionKey, token, 8 * 60 * 60, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(tokenKey, account.getId(), 8 * 60 * 60, TimeUnit.SECONDS);
            loginVO.setToken(token);
            loginVO.setPhone(phone);
            loginVO.setId(account.getId());
        }
        return ResponseDTO.successWithData(loginVO);
    }


    @RequestMapping("/account/backend/login")
    public ResponseDTO<LoginVO> login(Account account) {
        AssertUtil.isTrue(StringUtils.isBlank(account.getLoginName()), "请输入登录名");
        AssertUtil.isTrue(StringUtils.isBlank(account.getPassword()), "请输入密码");
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Account::getLoginName, account.getLoginName())
                .or()
                .eq(Account::getMobilePhone,account.getLoginName());
        Account getInfo = accountService.getOne(queryWrapper);
        if (ObjectUtil.isNull(getInfo)) {
            return ResponseDTO.wrap(ResponseCodeConst.ERROR_LOGIN_USERNAME);
        }
        //String md5Password = SecureUtil.md5(account.getPassword());
        if (!ObjectUtil.equal(getInfo.getPassword(),account.getPassword())) {
            return ResponseDTO.wrap(ResponseCodeConst.ERROR_LOGIN_PASSWORD);
        }
        Integer accountId = getInfo.getId();
        String sessionKey = SystemConstant.KEY_ACCOUNT + accountId.toString();
        // 生成 token
        String token = KeyUtils.getKey();
        String tokenKey = SystemConstant.KEY_TOKEN + token;
        // 将token存入缓存
        redisTemplate.opsForValue().set(sessionKey, token, 8 * 60 * 60, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(tokenKey, getInfo.getId(), 8 * 60 * 60, TimeUnit.SECONDS);

        LoginVO loginVO = EasyBeanUtil.copy(getInfo, LoginVO.class);
        loginVO.setToken(token);

        Map<String, String> map = new HashMap<>();
        map.put(ExecutionContext.USER_ID, getInfo.getId() + "");
        map.put(ExecutionContext.USER_NAME, getInfo.getName());
        map.put(ExecutionContext.LOGIN_NAME, getInfo.getLoginName());
        map.put(ExecutionContext.TOKEN, token);
        ExecutionContext.setContextMap(map);
        return ResponseDTO.successWithData(loginVO);
    }









}
